package cn.xzc.job.util;

import cn.xzc.job.constant.Constant;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;

/**
 * @author 熊志聪
 * @Classname ClassUtils
 * @Description class相关util
 * @Date 2024/2/16 16:47
 */
public class ClassUtil {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ClassUtil.class);

    public static boolean containAnnotation(AnnotatedElement type, Class<? extends Annotation> annotationType) {
        Annotation[] annotations = type.getDeclaredAnnotations();
        return containAnnotation(annotations, annotationType);
    }

    public static String[] getJavaClassPaths() {
        return System.getProperty("java.class.path").split(System.getProperty("path.separator"));
    }

    /**
     * Get the class name without the qualified package name.
     * 获取没有限定包名的类名。
     *
     * @param className the className to get the short name for
     * @return the class name of the class without the package name 没有package的className
     */
    public static String getShortName(String className) {
        int lastDotIndex = className.lastIndexOf(Constant.DOT);
        int nameEndIndex = className.indexOf(Constant.CGLIB_CLASS_SEPARATOR);
        if (nameEndIndex == -1) {
            nameEndIndex = className.length();
        }
        //去除className字符串$$后面部分
        String shortName = className.substring(lastDotIndex + 1, nameEndIndex);
        //将内部类的$并转成.
        return shortName.replace(Constant.NESTED_CLASS_SEPARATOR, Constant.DOT);
    }

    /**
     * 根据Class获取没有限定包名的类名。
     *
     * @param clazz Class
     * @return 没有限定包名的类名
     */
    public static String getShortName(Class<?> clazz) {
        String typeName = clazz.getTypeName();
        return getShortName(typeName);
    }

    public static ClassLoader getClassLoader() {
        ClassLoader classLoader = getContextClassLoader();
        return Objects.nonNull(classLoader) ? classLoader : Objects.nonNull(classLoader = ClassUtil.class.getClassLoader()) ? classLoader : getSystemClassLoader();
    }

    public static ClassLoader getContextClassLoader() {
        return Objects.isNull(System.getSecurityManager()) ? Thread.currentThread().getContextClassLoader() :
                AccessController.doPrivileged(
                        (PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader());
    }

    public static Class<?> loadClass(String className, boolean initialize, ClassLoader classLoader) {
        ClassLoader loader = Objects.isNull(classLoader) ? getClassLoader() : classLoader;
        try {
            return Class.forName(className, initialize, loader);
        } catch (NoClassDefFoundError | ClassNotFoundException e) {
            // 由于依赖库导致的类无法加载，直接跳过此类
            log.error("由于依赖库导致的类无法加载，直接跳过此类!\n{}", ThrowableUtil.getThrowableMessage(e));
        } catch (UnsupportedClassVersionError e) {
            // 版本导致的不兼容的类，跳过
            log.error("版本导致的不兼容的类,加载失败!\n{}", ThrowableUtil.getThrowableMessage(e));
        } catch (Throwable e) {
            log.error("其他原因导致的类加载失败!\n{}", ThrowableUtil.getThrowableMessage(e));
        }
        return null;
    }

    public static ClassLoader getSystemClassLoader() {
        return Objects.isNull(System.getSecurityManager()) ? ClassLoader.getSystemClassLoader() :
                AccessController.doPrivileged(
                        (PrivilegedAction<ClassLoader>) ClassLoader::getSystemClassLoader);
    }

    private static boolean containAnnotation(Annotation[] annotations, Class<? extends Annotation> annotationType) {
        if (ArrayUtil.isNotEmpty(annotations)) {
            for (Annotation annotation : annotations) {
                if (annotation.annotationType().equals(annotationType)) {
                    return true;
                }
            }
        }
        return false;
    }

}
